package com.yixia.web.controller.system;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yixia.common.core.domain.entity.SysDept;
import com.yixia.system.domain.system.SysUserRole;
import com.yixia.framework.web.service.SysPermissionService;
import com.yixia.framework.web.service.TokenService;
import com.yixia.system.service.system.SysDeptService;
import com.yixia.system.service.system.SysRoleService;
import com.yixia.system.service.system.SysUserService;
import com.yixia.common.core.domain.entity.SysRole;
import com.yixia.common.core.domain.entity.SysUser;
import com.yixia.common.core.domain.model.LoginUser;
import com.yixia.common.enums.BusinessType;
import com.yixia.common.core.controller.BaseController;
import com.yixia.common.core.domain.AjaxResult;
import com.yixia.common.annotation.Log;

import com.yixia.common.utils.StringUtils;
import com.yixia.common.utils.page.PageBean;
import com.yixia.common.utils.page.PageUtils;
import com.yixia.common.utils.page.TableDataInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

/**
 * 角色管理
 */
@Api(tags = "角色管理模块")
@Slf4j
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseController {

    @Autowired
    private SysRoleService roleService;

    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysDeptService deptService;

    @Autowired
    private TokenService tokenService;

    /**
     * COMMIT : 已完成
     * 根据条件分页查询角色信息
     * 角色 + 分页条件
     */
    @ApiOperation("分页查询")
    @PreAuthorize("@yixia.hasPermi('system:role:list')")
    @GetMapping("/list")
    public AjaxResult list(SysRole role) {
        /*里面都获取请求参数中的元素并将其封装为page对象*/
        PageBean pageBean = PageUtils.startPageBean();
        /*进行分页查询*/
        return roleService.slectRolePageList(pageBean, role);/*返回的是page的数据集合*/
    }


    /**
     * 添加
     */
    @ApiOperation("添加角色")
    @Log(title = "角色管理", businessType = BusinessType.INSERT)
    @PreAuthorize("@yixia.hasPermi('system:role:add')")
    @PostMapping("/add")
    public AjaxResult add(@RequestBody SysRole role){
        /*将sysRole的信息存入数据库中*/
        /*要对选择的信息进行解析*/
        /*解析后才能存入*/
        /*1.先看角色名是否存在*/
        if(!roleService.checkRoleNameUnique(role)){
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
        }
        /*2.看角色的权限字段是否存在*/
        else if (!roleService.checkRoleKeyUnique(role))
        {
            return AjaxResult.error("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        /*3.将角色添加到数据库中*/
        return toAjax(roleService.insertRole(role));
    }



    /**
     * 修改角色
     * 1、校验角色是否允许操作
     * 2、校验角色是否有数据权限
     * @param role
     * @return
     */
    @PutMapping("/edit")
    public AjaxResult edit(@RequestBody SysRole role){

        /*1. 校验角色是否允许操作*/
        roleService.checkRoleAllowed(role);

        /*2. 校验角色是否有数据权限*/
        roleService.checkRoleDataScope(role.getRoleId());

        /*3. 判断角色名称是否存在*/
        if(!roleService.checkRoleNameUnique(role)){
            return error("修改角色'" + role.getRoleName() + "'失败，角色名称已存在");
        }
        /*4. 判断角色权限字段是否存在*/
        else if(!roleService.checkRoleKeyUnique(role)){
            return error("修改角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }

        /*5. 进行修改操作*/
        if(roleService.updateRole(role)){
            /*6. 修改成功后更新缓存*/
            /*获取登录用户的信息*/
            LoginUser loginUser = getLoginUser();

            /*当前登录者的ID存在并且当前登录者不是超级管理员是*/
            if(StringUtils.isNotNull(loginUser.getUserId()) && !loginUser.getUser().isAdmin()){
                /*重新将登录角色的权限获取出来---更新角色菜单权限，更新角色信息，并将其保存到token中*/
                loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
                loginUser.setUser(userService.getByUsername(loginUser.getUser().getUsername()));
                tokenService.setLoginUser(loginUser);
            }
            return success();
        }
        return error("修改角色'" + role.getRoleName() + "'失败，请联系管理员");
    }

    /**
     * 批量删除角色信息
     * 1. 判断该角色是否允许操作
     * 2. 判断该角色是否有数据权限
     * 3. 判断该角色是否分配给了用户--分配给了用户的角色不能删除
     * 4. 根据角色ID删除角色菜单表
     * 5. 根据id删除角色表中的信息
     * @param roleIds
     * @return
     */
    @DeleteMapping("/delete/{roleIds}")
    public AjaxResult remove(@PathVariable Long[]  roleIds){
        return toAjax(roleService.deleteRoleByIds(roleIds));
    }


    /**
     * 修改角色状态
     * @param role
     * @return
     */
    @PutMapping("/changeStatus")
    public AjaxResult editStatus(@RequestBody SysRole role){
        /*1.先校验角色是否运行该操作*/
        roleService.checkRoleAllowed(role);
        /*2.校验角色是否有数据权限*/
        roleService.checkRoleDataScope(role.getRoleId());

        /*3.通过id来进行修改*/
        /*4.返回*/
        return toAjax(roleService.updateRoleStatus(role));
    }


    /**
     * 根据角色ID获取角色信息
     * 1. 校验角色是否有数据权限
     * @param roleId
     * @return
     */
    @GetMapping("/getInfoById/{roleId}")
    public AjaxResult getInfoById(@PathVariable Long roleId){

        roleService.checkRoleDataScope(roleId);

        return success(roleService.selectRoleById(roleId));
    }


    /**
     * 查询已分配的用户信息
     */
    @PreAuthorize("@yixia.hasPermi('system:role:list')")
    @GetMapping("/authUser/allocatedList")
    public TableDataInfo allocatedList(SysUser user){
        PageBean pageBean = startPage();
        /*直接进行分页查询*/
        Page<SysUser> list = new Page<>();
        if (StringUtils.isNotEmpty(user.getRoleId())) {
            list = userService.selectAllocatedList(pageBean, user);
        }
        /*进行分页查询*/
        return getDataTable(list);
    }

    /**
     * 查询未分配的用户信息
     * @param user
     */
    @PreAuthorize("@yixia.hasPermi('system:role:list')")
    @GetMapping("/authUser/unallocatedList")
    public TableDataInfo unallocatedList(SysUser user){

        PageBean pageBean = startPage();
        /*直接进行分页查询*/
        Page<SysUser> list = new Page<>();
        if (StringUtils.isNotEmpty(user.getRoleId())) {
            list = userService.selectUnAllocatedList(pageBean, user);
        }
        /*进行分页查询*/
        return getDataTable(list);
    }

    /**
     * 将一个角色发给多个用户
     * @param roleId 要分配的角色ID
     * @param userIds 分发给的用户ID
     * @return 返回信息
     */
    @Log(title = "用户管理---将一个角色发给多个用户", businessType = BusinessType.GENCODE)
    @PutMapping("/authUser/selectAll")
    public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds){
        /*判断该角色是否有数据权限*/
        roleService.checkRoleDataScope(roleId);
        /*进行分发*/
        return toAjax(roleService.insertAuthUsers(roleId, userIds));
    }


    /**
     * 取消授权用户
     */
    @PutMapping("/authUser/cancel")
    @Log(title = "角色管理---取消授权用户", businessType = BusinessType.DELETE)
    public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
    {
        return toAjax(roleService.deleteAuthUser(userRole));
    }

    /**
     * COMMIT: 已完成
     * 修改保存数据权限
     */
    @PreAuthorize("@yixia.hasPermi('system:role:edit')")
    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping("/dataScope")
    public AjaxResult dataScope(@RequestBody SysRole role)
    {
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        return toAjax(roleService.authDataScope(role));
    }


    /**
     * 批量取消角色授权给用户 + 取消单个
     * @param roleId 角色ID
     * @param userIds 用户ID集合
     * @return 返回状态
     */
    @PutMapping("/authUser/cancelAll")
    @Log(title = "角色管理---批量取消授权用户", businessType = BusinessType.DELETE)
    public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds){
        return toAjax(roleService.deleteAuthUsers(roleId, userIds));
    }


    /**
     * COMMIT : 已完成
     * 获取对应角色部门树列表
     */
    @PreAuthorize("@yixia.hasPermi('system:role:query')")
    @GetMapping(value = "/deptTree/{roleId}")
    public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
    {
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
        ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
        return ajax;
    }




}
